package com.food.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.food.user.entity.UserAccount;
import com.food.user.entity.UserAccountInfo;
import com.food.user.exception.userAccountException.UserAccountException;
import com.food.user.exception.userAccountException.UserAccountExceptionCode;
import com.food.user.form.*;
import com.food.user.mapper.UserAccountInfoMapper;
import com.food.user.mapper.UserAccountMapper;
import com.food.user.service.UserAccountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.food.user.util.*;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 帅得一
 * @since 2023年06月17日
 */
@Service
public class UserAccountServiceImpl extends ServiceImpl<UserAccountMapper, UserAccount> implements UserAccountService {

    @Autowired
    private UserAccountMapper userAccountMapper;
    @Autowired
    private UserAccountInfoMapper userAccountInfoMapper;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public void register(UserAccountRegisterForm form) throws Exception {
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_phone",form.getUserPhone());
        UserAccount userAccount = userAccountMapper.selectOne(queryWrapper);
        if(userAccount!=null){
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PHONE_EXIST);
        }
        String key = RedisKeyUtil.loginByPhone(form.getUserPhone());
        System.out.println(key);
        if(!redisUtil.hasKey(key)){//验证码失效
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PHONE_CODE_TIME_OUT);
        }
        String send = redisUtil.getValue(key);
        if(!form.getCode().equals(send)){//验证码错误
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PHONE_CODE_ERROR);
        }
        String userName = "user"+form.getUserPhone().substring(form.getUserPhone().length()-4);
        //如果userName已经存在了 userName+1
        QueryWrapper<UserAccount> userAccountQueryWrapper = new QueryWrapper<>();
        userAccountQueryWrapper.eq("user_name",userName);
        UserAccount one = userAccountMapper.selectOne(userAccountQueryWrapper);
        while(one!=null){
            userName+=1;
            one = userAccountMapper.selectOne(userAccountQueryWrapper);
        }
        UserAccount userAccount1 = BeanUtil.toBean(form, UserAccount.class);
        userAccount1.setUserName(userName);
        //插入新数据 并且获取刚刚插入的数据的自增id
        userAccountMapper.insert(userAccount1);
        Long userId=userAccount1.getUserId();
        //同时往info表中 新增一条数据
        UserAccountInfo userAccountInfo = new UserAccountInfo();
        userAccountInfo.setUserId(userId);
        userAccountInfoMapper.insert(userAccountInfo);

        //注册成功后删除验证码那个键
        redisUtil.delete(key);
    }

    @Override
    public UserAccount login(UserLoginForm form) throws Exception {
        QueryWrapper<UserAccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_name",form.getUserName());
        UserAccount userAccount = userAccountMapper.selectOne(queryWrapper);
        if(userAccount==null){//未注册
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_NOT_REGISTER);
        }
        //判断账号密码是否匹配
        if(!form.getUserPassword().equals(userAccount.getUserPassword())){
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PASSWORD_ERROR);
        }
        return userAccount;
    }

    @Override
    public void sendCode(CodePhoneForm form) throws Exception {
         //判断redis中是否已经存在register:codeonminute:phone:手机号
        if(redisUtil.hasKey(RedisKeyUtil.onMinuteCodeKey(form.getPhone()))){
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_SEND_CODE_FREQUENT);
        }
        //判断一个小时内是否已经发送过五条了
        if(redisUtil.hasKey(RedisKeyUtil.onHourCodeKey(form.getPhone())) && Integer.parseInt(redisUtil.getValue(RedisKeyUtil.onHourCodeKey(form.getPhone())))==5){
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_SEND_CODE_FIVETIMES);
        }
//        String send = SMSUtil.send(form.getPhone());
        String key = RedisKeyUtil.loginByPhone(form.getPhone());
        //将短信验证码存入redis中
        redisUtil.setValue(key,123456+"",60*5L);
        //还需要存一个键值对用于查询一分钟内是否已经发送过验证码了
        redisUtil.setValue(RedisKeyUtil.onMinuteCodeKey(form.getPhone()),123456+"",60L);
        //需要再存一个用于保存一小时内是否发送过五次的键值对
        if(!redisUtil.hasKey(RedisKeyUtil.onHourCodeKey(form.getPhone()))){
            redisUtil.setValue(RedisKeyUtil.onHourCodeKey(form.getPhone()),"0",60*60L);
        }
        redisUtil.inc(RedisKeyUtil.onHourCodeKey(form.getPhone()));
    }

    @Override
    public UserAccount loginByPhone(CodePhoneLoginForm form) throws Exception {
        //通过手机号获取redis中的key
        String key = RedisKeyUtil.loginByPhone(form.getPhone());
        //判断短信验证码
        if(!redisUtil.hasKey(key)){
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PHONE_CODE_TIME_OUT);
        }
        //通过号码获取redis中存储的短信验证码
        String send =redisUtil.getValue(key);
        if(!form.getCode().equals(send)){
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PHONE_CODE_ERROR);
        }
        //查询手机号是否正确
        QueryWrapper<UserAccount> userAccountQueryWrapper = new QueryWrapper<>();
        userAccountQueryWrapper.eq("user_phone",form.getPhone());
        UserAccount userAccount = userAccountMapper.selectOne(userAccountQueryWrapper);
        if(userAccount==null){//未注册的手机号
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_NOT_REGISTER);
        }
        return userAccount;
    }

    @Override
    @Transactional
    public void updatePassword(UpdatePasswordForm form) throws Exception {
        //修改当前登录用户的密码，通过token获取当前登录用户的信息
        System.out.println(form);
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        Integer id = JwtUtil.getUserId(accessToken);
        UserAccount userAccount = userAccountMapper.selectById(id);
        if (!userAccount.getUserPhone().equals(form.getUserPhone())){
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_NOT_REGISTER);
        }
        String key=RedisKeyUtil.loginByPhone(form.getUserPhone());
        if(!redisUtil.hasKey(key)){//验证码过期
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PHONE_CODE_TIME_OUT);
        }
        String send=redisUtil.getValue(key);
        if(!form.getCode().equals(send)){//验证码错误
            throw new UserAccountException(UserAccountExceptionCode.USER_ACCOUNT_PHONE_CODE_ERROR);
        }
        if(form.getNewUserPassword().equals(userAccount.getUserPassword())){//新旧密码重复
            throw new UserAccountException(UserAccountExceptionCode.USER_PASSWORD_EQUAL);
        }
        if(!form.getOldUserPassword().equals(userAccount.getUserPassword())){//原密码输入错误
            throw new UserAccountException(UserAccountExceptionCode.USER_OLD_PASSWORD_ERROR);
        }
        userAccount.setUserPassword(form.getNewUserPassword());
        userAccountMapper.updateById(userAccount);
        redisUtil.delete(key);
    }

    @Override
    public void updateUserNickName(UpdateUserNickNameForm form) {
        //修改当前登录的用户信息
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        Integer id = JwtUtil.getUserId(accessToken);
        UserAccount userAccount = userAccountMapper.selectById(id);
        userAccount.setUserNickName(form.getUserNickName());
        userAccountMapper.updateById(userAccount);
    }

    @Override
    public UserAccount showMyAccount() {
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        Integer id = JwtUtil.getUserId(accessToken);
        UserAccount userAccount = userAccountMapper.selectById(id);
        return userAccount;
    }

    @Override
    public void out() {
        String accessToken = WebUtil.getRequest().getHeader("accessToken");
        //删除当前redis中保存的accessToken
        redisUtil.delete(accessToken);
    }


}

